﻿using System;
using System.Security.Cryptography;
using Oblivion.Clients;
using Oblivion.Networking.Encryptions;

namespace Oblivion.Networking.Packets
{
    public class EncryptionRequestPacket
    {
        // private Packet pkt;
        public byte[] PublicKey;
        public string ServerID;
        public byte[] VerifyToken;

        public EncryptionRequestPacket(GameClient client)
        {
            //pkt = new Packet(PacketType.EncryptionRequest);
            ServerID = client.Hash;
        }

        public byte[] Build()
        {
            //verifyToken is 4 random bytes
            VerifyToken = new byte[4];
            var csp = new RNGCryptoServiceProvider();
            csp.GetBytes(VerifyToken);

            AsnKeyBuilder.AsnMessage encodedkey = AsnKeyBuilder.PublicKeyToX509(Program.ServerKey);
            PublicKey = encodedkey.GetBytes();

            var pkt = new Packet(PacketType.EncryptionRequest);
            pkt.WriteString(ServerID);
            pkt.WriteInt16((short) PublicKey.Length);
            pkt.WriteUInt8Array(PublicKey);
            pkt.WriteInt16((short) VerifyToken.Length);
            pkt.WriteUInt8Array(VerifyToken);

            return pkt.Finalize();
        }


        public static string CreateHash()
        {
            byte[] hash = CreateInt32(new Random().Next());
            string response = "";
            foreach (byte b in hash)
            {
                if (b < 0x10)
                    response += "0";
                response += b.ToString("x");
            }
            return response;
        }

        /// <summary>
        /// Creates a Minecraft-Style 32 bit Integer
        /// Used for the client HASH
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static byte[] CreateInt32(int value)
        {
            unchecked
            {
                return new[]
                           {
                               (byte) (value >> 24), (byte) (value >> 16),
                               (byte) (value >> 8), (byte) (value)
                           };
            }
        }
    }
}